//
//  CardCollectionViewController.swift
//  TSListDemo
//
//  Created by qian on 2020/11/6.
//  Copyright © 2020 dvlproad. All rights reserved.
//

import UIKit
import SnapKit

let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height

func synchronized(_ lock: Any, closure: () -> ()) {
    objc_sync_enter(lock)
    closure()
    objc_sync_exit(lock)
}

class CardCollectionViewController: UIViewController {
    fileprivate let identifier = "CQTableViewCardCollectionViewCell"
    fileprivate var pages = 1
    fileprivate var limit = 10 // 每页限定10条数据
    
    private var isLeft: Bool?
    fileprivate var allDataSource: [UIImage] = [] // 需要显示的所有数据
    fileprivate var dataSource: [UIImage] = [] // 屏幕上显示的cell数据源
    fileprivate var insertIndex = 0 // 从allDataSource中拿一条数据 插入到dataSource中
    fileprivate var visibleCellsCount = 4 // 屏幕上显示cell的个数
    var collectionView: UICollectionView?
    fileprivate var isAnimating = false
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupCollectionView()
        // Do any additional setup after loading the view.
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        guard self.allDataSource.count == 0 else { return }
        requestData(false)
    }
    
    private func setupCollectionView() {
        
        let collectionViewFlowLayout = CQTTCardCollectionViewFlowLayout.init(leftRightPadding: 10, topPadding: 30, bottomPadding: 20)
        
        
        collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: collectionViewFlowLayout)
        collectionView?.backgroundColor = #colorLiteral(red: 0.9372549057, green: 0.3490196168, blue: 0.1921568662, alpha: 1)
        collectionView?.scrollsToTop = false
        
        collectionView?.register(UINib(nibName: "CQTableViewCardCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: identifier)
        collectionView?.register(CQTableViewCardCollectionViewCell.self, forCellWithReuseIdentifier: identifier)
        collectionView?.dataSource = self
        collectionView?.delegate = self
        self.view.addSubview(collectionView!)
        collectionView?.snp_makeConstraints({ (make) in
            make.centerX.equalTo(self.view)
            make.left.equalTo(self.view).offset(10)
            make.top.equalTo(self.view).offset(100)
            make.bottom.equalTo(self.view).offset(-40)
        })
        
        collectionView?.layoutIfNeeded()
        
        
        addPanGest()
    }
    private func addPanGest() {
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.panGestHandle(_:)))
        self.collectionView?.addGestureRecognizer(panGesture)
    }
    
    fileprivate func requestData(_ refreshNext: Bool) {
        
        var array = [UIImage]()
        for i in 0..<10 {
            guard let image = UIImage(named: "image\(i)") else { return }
            array.append(image)
        }
        
        self.pages += refreshNext && array.count >= limit ? 1 : 0
        synchronized(self.dataSource) {
            self.allDataSource.append(contentsOf: array)
            if self.pages == 1 {
                if array.count > self.visibleCellsCount {
                    var newArray = [UIImage]()
                    newArray = array[0,1,2,3]
                    self.dataSource.append(contentsOf: newArray)
                    self.insertIndex = self.visibleCellsCount
                } else {
                    self.dataSource.append(contentsOf: array)
                    self.insertIndex = 0
                }
            }
        }
        self.collectionView?.reloadData()
    }
    
    @objc private func panGestHandle(_ panGest: UIPanGestureRecognizer) {
        guard !isAnimating else { return }
        guard let cell = ((collectionView?.cellForItem(at:IndexPath(row: 0, section: 0) )) as? CQTableViewCardCollectionViewCell), self.allDataSource.count > 1 else {
            return
        }
        guard let lastCell = (collectionView?.cellForItem(at:IndexPath(row: 3, section: 0))) else {
            return
        }
        let movePoint = panGest.translation(in: self.collectionView)
        collectionView?.movetoPoint = movePoint
        if (panGest.state == .began) {
            debugPrint("pan begin...")
            for tempCell in collectionView!.visibleCells {
                guard let tempCardCell = tempCell as? CQBaseCardCollectionViewCell else { return }
                tempCardCell.originalCenter = CGPoint(x: tempCardCell.frame.origin.x + tempCardCell.frame.size.width/2, y: tempCardCell.frame.origin.y + tempCardCell.frame.size.height/2)
                tempCardCell.originalFrame = tempCardCell.frame
            }
            
        } else if (panGest.state == .changed) {
            debugPrint("pan changed...")
            cell.center = CGPoint(x: cell.center.x + movePoint.x, y: cell.center.y + movePoint.y )
            cell.currentAngle = (cell.center.x - cell.frame.size.width / 2.0) / cell.frame.size.width / 4.0;
            cell.transform = CGAffineTransform(rotationAngle: cell.currentAngle!)
            
            let cellNewCenterX = cell.center.x
            var cellNewCenterY = cell.center.y
            let cellOriginalCenterX = cell.originalCenter?.x ?? 0
            let cellOriginalCenterY = cell.originalCenter?.y ?? 0
            
            // 更新限制本移动Cell的 CenterY
            var moveOffsetY: CGFloat = cell.center.y - cellOriginalCenterY
            let moveBoundaryYMax: CGFloat = 40
            if moveOffsetY > moveBoundaryYMax {
                moveOffsetY = min(moveBoundaryYMax, moveOffsetY)
            }
            if moveOffsetY < -moveBoundaryYMax {
                moveOffsetY = max(-moveBoundaryYMax, moveOffsetY)
            }
            debugPrint("pan changed...moveOffsetY=\(moveOffsetY)")
            cellNewCenterY  = cellOriginalCenterY + moveOffsetY
            cell.center = CGPoint.init(x: cellNewCenterX, y: cellNewCenterY)
            
            // 处理 X
            let moveOffsetX: CGFloat = cell.center.x - cellOriginalCenterX
            let moveBoundaryXMin: CGFloat = 40
            let moveBoundaryXMax: CGFloat = 80
            let moveOffsetXPositive: CGFloat = abs(moveOffsetX)
            var movePercentValue: CGFloat = 0
            if moveOffsetXPositive < moveBoundaryXMin {
                movePercentValue = 0
            } else if moveOffsetXPositive >= moveBoundaryXMax {
                movePercentValue = 1
            } else {
                movePercentValue = (moveOffsetXPositive-moveBoundaryXMin)/(moveBoundaryXMax-moveBoundaryXMin)
            }
            debugPrint("pan changed...moveOffsetX=\(moveOffsetX), movePercentValue=\(movePercentValue)")
            if moveOffsetX < 0 {
                cell.hateView.alpha = movePercentValue
                cell.likeView.alpha = 0
            } else {
                cell.hateView.alpha = 0
                cell.likeView.alpha = movePercentValue
            }
            
            isLeft = (moveOffsetX < 0)
            let _ = collectionView?.visibleCells.filter({$0 !== cell && $0 !== lastCell}).map({
                guard let card = $0 as? CQBaseCardCollectionViewCell else { return }
                

                let collectionViewLayout: CQTBaseCardCollectionViewFlowLayout = self.collectionView?.collectionViewLayout as! CQTBaseCardCollectionViewFlowLayout
                let movePointOffset = CGPoint(x: moveOffsetX, y: moveOffsetY)
                card.resetlayoutWithOffset(movePointOffset, collectionViewLayout: collectionViewLayout)
            })
            panGest.setTranslation(.zero, in: self.collectionView)
            
        } else if (panGest.state == .ended) {
            debugPrint("pan ended...")
            let vel = panGest.velocity(in: self.collectionView)
            let centerOffsetX = UIScreen.main.bounds.size.width / 3.0
            
            // 如果拖动超过一定幅度，则进入下一张
            if (vel.x > centerOffsetX || vel.x < -centerOffsetX)  {
                self.remove()
                return ;
            }
            
            // 如果拖动没超过一定幅度，则进入下一张
            
            //            let removeLeftX: CGFloat =  150
            //            let removeRightX: CGFloat = cell.frame.size.width - 150
            
            let collectionViewWidth: CGFloat = (self.collectionView?.frame.size.width)!
            let removeLeftX: CGFloat =  collectionViewWidth/4*1 // 进入移出的左边界
            let removeRightX: CGFloat = collectionViewWidth/4*3 // 进入移出的由边界
            
            let cellMaxX: CGFloat = cell.frame.origin.x + cell.frame.size.width
            let cellMinX: CGFloat = cell.frame.origin.x
            let isRemoveFromLeft: Bool = cellMaxX < removeLeftX
            let isRemoveFromRight: Bool = cellMinX > removeRightX
            if (isRemoveFromLeft || isRemoveFromRight) {
                self.remove()
            } else {
                UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseOut, animations: {
                    cell.center = cell.originalCenter!
                    cell.transform = CGAffineTransform(rotationAngle: 0)
                    let _ = self.collectionView?.visibleCells.filter({$0 !== cell && $0 !== lastCell}).map({
                        guard let card = $0 as? CQBaseCardCollectionViewCell else { return }
                        
                        let collectionViewLayout: CQTBaseCardCollectionViewFlowLayout = self.collectionView?.collectionViewLayout as! CQTBaseCardCollectionViewFlowLayout
                        card.resetlayoutWithOffset(.zero, collectionViewLayout: collectionViewLayout)
                    })
                })
            }
        }
    }
    
    private func remove() {
        isAnimating = true
        let cell = collectionView?.cellForItem(at:IndexPath(row: 0, section: 0) ) as! CQBaseCardCollectionViewCell
        UIView.animate(withDuration: 0.3, animations: {
            let cellCurrentAngle: CGFloat = cell.currentAngle ?? 1
            let cellWidth: CGFloat = cell.frame.size.width
            let cellHeight: CGFloat = cell.frame.size.height
            if (self.isLeft!) { // left
                let cellCenterX = -cellWidth / 2
                cell.center = CGPoint(x: cellCenterX, y: cell.center.y - cellCurrentAngle * cellHeight);
            } else {            // right
                let screenWidth = UIScreen.main.bounds.width
                let cellCenterX = screenWidth + cellWidth / 2
                cell.center = CGPoint(x: cellCenterX, y: cell.center.y + cellCurrentAngle * cellHeight);
            }
        })
        let user = self.dataSource.first
        cell.alpha = 0
        cell.center = cell.originalCenter!
        if self.insertIndex >= self.allDataSource.count {
            self.insertIndex = 0
        }
        self.dataSource.remove(at: 0)
        self.collectionView?.deleteItems(at: [IndexPath(item: 0, section: 0)])
        self.collectionView?.performBatchUpdates({
            self.dataSource.append(self.allDataSource[self.insertIndex])
            let insert = min(self.visibleCellsCount - 1, self.allDataSource.count - 1)
            self.collectionView?.insertItems(at: [IndexPath(item: insert, section: 0)])
            
        }, completion: { (comlete) in
            self.isAnimating = !comlete
            // 计算可见cell的indexpath值
            let cell1 = self.collectionView?.cellForItem(at:IndexPath(row: 0, section: 0) ) as! CQBaseCardCollectionViewCell
            let lastCell = self.collectionView?.cellForItem(at:IndexPath(row: 3, section: 0) ) as! CQBaseCardCollectionViewCell
            let _ = self.collectionView?.visibleCells.filter({$0 !== cell1 && $0 !== lastCell}).map({
                guard let card = $0 as? CQBaseCardCollectionViewCell else { return }
                card.indexPathItem -= 1
            })
        })
        
        self.insertIndex += 1
        if self.insertIndex == (self.pages - 1) * 10 + 7 {
            self.requestData(true)
        }
    }
}

extension CardCollectionViewController: UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath) as! CQTableViewCardCollectionViewCell
        cell.indexPathItem = indexPath.row
        cell.likeView.alpha = 0
        cell.hateView.alpha = 0
        cell.tableView.contentOffset = CGPoint.zero
//        let image = dataSource[indexPath.row]
//        cell.imageView.image = image
        return cell
    }
}

extension CardCollectionViewController: UICollectionViewDataSource {
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return dataSource.count
    }
}

